home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-06-23 | 38.0 KB | 2,008 lines |
- OPT D-
- COMMENT HEAD=%111
- OUTPUT E:\WHIP!\VLM\NAILSPIN.VLM
- TEXT
-
- scrxbytes: = 320*2
- scrlines: = 240
- scrsize: = scrxbytes*scrlines
-
- envlightrot: = 1 * Rotating envmap or still.
-
- envmapxres: = 320 * / the clipwindow
- envmapyres: = 240 * \ dimensions
-
- maxpoints: = 500 * maximum number of points in object
- maxedges: = 1000 * maximum number of edges in object
- maxtriangles: = 500 * maximum number of triangles in object
- avgedgelen: = 50 * maximum average length of edges
-
- * Internal point-structure (with texture-coordinates)
- RSRESET
- pointx: RS.W 1
- pointy: RS.W 1
- pointtx: RS.W 1
- pointty: RS.W 1
- pointz: RS.W 1
- pointsize: RS.W 1
-
- * Internal triangle format (with color & hiddenedge info)
- RSRESET
- trianglep1: RS.W 1
- trianglep2: RS.W 1
- trianglep3: RS.W 1
- triangleinfo: RS.W 1
- trianglesize: RS.W 1
-
- RSRESET
- edgelength: RS.W 1
- edgestarty: RS.W 1
- edgeslope: RS.L 1
- edgeheadersize: RS.W 1
-
- RSRESET
- edgex: RS.W 1
- edgetx: RS.W 1
- edgety: RS.W 1
- edgeentrysize: RS.W 1
-
- *** VLM STRUCTURE **************************************************************
-
- DC.B "VLM2" ;vlm module type
- DC.L infotext ;pointer to infotext
- DC.L settings ;pointer to settings-structure
- DC.L init ;pointer to init routine
- DC.L deinit ;pointer to deinit routine
- DC.L main ;pointer to mainloop routine
-
- * Libs
- INCLUDE FIMATH.I
- TEXT
-
- ;SERVICE ROUTINES PROVIDED BY THE CALLING PROGRAM
- set_vblrout:
- ;a0: new vbl subroutine
- movea.l service_struct,A1
- movea.l (A1),A1
- jsr (A1)
- rts
-
- wait_vbl:
- movea.l service_struct,A1
- movea.l 4(A1),A1
- jsr (A1)
- rts
-
- set_scradr:
- ;a0: new screen adress
- movea.l service_struct,A1
- movea.l 8(A1),A1
- jsr (A1)
- rts
-
- set_resolution:
- ;d0: number of the wanted resolution
- movea.l service_struct,A1
- movea.l 12(A1),A1
- jsr (A1)
- rts
-
- get_left_spec:
- movea.l service_struct,A1
- movea.l 16(A1),A1
- jsr (A1) ;returns in a0 the adress of left spec
- rts
-
- get_right_spec:
- movea.l service_struct,A1
- movea.l 20(A1),A1
- jsr (A1) ;returns in a0 the adress of right spec
- rts
-
- get_left_volume:
- movea.l service_struct,A1
- movea.l 24(A1),A1
- jsr (A1) ;returns in d0 the left volume value
- rts
-
- get_right_volume:
- movea.l service_struct,A1
- movea.l 28(A1),A1
- jsr (A1) ;returns in d0 the right volume value
- rts
-
- get_left_osci:
- movea.l service_struct,A1
- movea.l 32(A1),A1
- jsr (A1) ;returns in a0 the adress of osci data
- rts
-
- get_right_osci:
- movea.l service_struct,A1
- movea.l 36(A1),A1
- jsr (A1) ;returns in a0 the adress of osci data
- rts
-
- service_struct: DC.L 0 ;must be set in 'init'
-
- ********************************************************************************
-
- infotext:
- DC.B "NAILSPIN 3D (sKINNY pUPPY)",0
- DC.B "author: EarX/FUN",0
- DC.B "version: 1.2",0
- DC.B "date: 13-06-1999" ,0
- DC.B 0
- EVEN
-
- settings: DC.L 7
-
- DC.L parname1_txt
- DC.L 3 ;parameter type = slider
- distance: DC.L 400 ;parametervalue
- DC.L distslider_tbl
-
- DC.L parname2_txt
- DC.L 3
- rotspeed: DC.L 7
- DC.L spedslider_tbl
-
- DC.L parname3_txt
- DC.L 3
- objectvibr: DC.L 300
- DC.L vibrslider_tbl
-
- DC.L parname4_txt
- DC.L 1
- rotswitch: DC.L 0
- DC.L 0
-
- DC.L parname5_txt
- DC.L 3
- peaktreshold: DC.L 16384
- DC.L peakslider_tbl
-
- DC.L parname6_txt
- DC.L 3
- objectresp: DC.L 50
- DC.L respslider_tbl
-
- DC.L parname7_txt
- DC.L 2
- objecttraject: DC.L 0
- DC.L trajselect_tbl
-
- distslider_tbl: DC.L 0
- DC.L 800
-
- spedslider_tbl: DC.L 0
- DC.L 15
-
- vibrslider_tbl: DC.L 0
- DC.L 600
-
- respslider_tbl: DC.L 0
- DC.L 200
-
- peakslider_tbl: DC.L 0
- DC.L 32768
-
- trajselect_tbl: DC.L 2
- DC.B "SINE-O-MATIC",0
- DC.B "STEREOID-PHONIC",0
-
- parname1_txt: DC.B "CAMERA DISTANCE",0
- parname2_txt: DC.B "OBJECT ROTATION",0
- parname3_txt: DC.B "OBJECT VIBRATION",0
- parname4_txt: DC.B "ROTATIONSWITCH",0
- parname5_txt: DC.B "ROTATIONSWITCH TRESHOLD",0
- parname6_txt: DC.B "ROTATIONSWITCH RESPONSE",0
- parname7_txt: DC.B "TRAJECTORY",0
- EVEN
-
- init:
- ;a0: service structure
- move.l A0,service_struct
-
- moveq #1,D0 * set resolution to 320x240
- bsr set_resolution
-
- * Initialize screenaddresses..
- .ramok: lea scr,a0
- move.l #scr_buf,d0
- addq.l #4,d0 * / long even
- andi.b #%11111100,d0 * \ address..
- move.l d0,(a0)+
- addi.l #scrsize,d0
- move.l d0,(a0)+
- addi.l #scrsize,d0
- move.l d0,(a0)+
-
- REPT 3
- moveq #0,d0
- moveq #0,d1
- move.w #envmapxres-1,d6
- move.w #envmapyres-1,d7
- bsr CLEAR_RECTANGLE
- bsr switch_screens
- ENDR
-
- bsr SET_ENVTORUS
- rts
-
- deinit:
- rts
-
- main: bsr switch_screens
- bsr PLOT_ENVMAP320200
- rts
-
- PLOT_ENVMAP320200:
- .decrease_peak:
- move.w .peak(pc),d0
- subi.w #256,d0
- bcs.s .skip_store
- move.w d0,.peak
- .skip_store:
- .end_decreasepeak
- .calc_vol:
- bsr get_left_volume
- move.w d0,.leftvol
- moveq #0,d7
- move.w d0,d7
- bsr get_right_volume
- move.w d0,.rightvol
- moveq #0,d1
- move.w d0,d1
- add.l d1,d7
- lsr.l #1,d7
- .end_calcvol
- tst.w rotswitch+2
- beq.s .end_rotswitch
-
- cmp.w peaktreshold+2,d7
- blo.s .no_reverse
- cmp.w .peak(pc),d7
- bcs.s .no_reverse
- move.w $4bc.w,d1
- sub.w .start4bc(pc),d1
- cmp.w objectresp+2,d1
- blo.s .no_reverse
- not.w .inverse
- move.w d7,.peak
- move.w $4bc.w,.start4bc
- move.w .lastrot(pc),.startrot
- .no_reverse:
- .end_rotswitch:
-
- move.w d7,-(sp)
-
- * First of all, clear the painted object from the current screenbuffer.
- movem.w .rect_tbl(pc),d0-d1/d6-d7
- bsr CLEAR_RECTANGLE
-
- * Now calculate everything and prepare for painting to the screen.
- movea.l envobjadr,a1
- lea .rot_tbl(pc),a2
-
- .inversecontrol:
- tst.w .inverse(pc)
- beq.s .pos
- move.w .startrot(pc),d0
- sub.w $4bc.w,d0
- add.w .start4bc(pc),d0
- bra.s .end_control
- .pos: move.w .startrot(pc),d0
- add.w $4bc.w,d0
- sub.w .start4bc(pc),d0
- .end_control:
- move.w d0,.lastrot
-
- move.w d0,d1
- mulu.w rotspeed+2,d0
- lsr.l #1,d0
- move.w d0,(a2)
- mulu.w rotspeed+2,d1
- lsl.l #2,d1
- move.l d1,d2
- add.l d1,d1
- add.l d2,d1
- lsr.l #4,d1
- move.w d1,2(a2)
- bsr ROTATE_OBJECT
- move.w (sp)+,d7
- .calc_xy:
- lea sine_tbl,a0
- move.w $4bc.w,d0
- move.w d0,d1
- Do_SinModulo d0
- Get_Sin a0,d0,d0
- mulu.w #7,d1
- lsr.w #1,d1
- Do_SinModulo d1
- Get_Sin a0,d1,d1
- asr.w #7,d0
- asr.w #8,d1
- tst.w objecttraject+2
- beq.s .end_calcxy
- tst.w .invertposx(pc)
- bne.s .do_posxinverse
- move.w .rightvol(pc),d0
- sub.w .leftvol(pc),d0
- bra.s .end_inverse
- .do_posxinverse:
- move.w .leftvol(pc),d0
- sub.w .rightvol(pc),d0
- .end_inverse:
- asr.w #7,d0
- add.w d0,.objectposx
- move.w .objectposx(pc),d0
- bmi.s .objnegx
- cmpi.w #200,d0
- blt.s .end_calcxy
- move.w #200,d0
- not.w .invertposx
- bra.s .end_calcxy
- .objnegx:
- cmpi.w #-200,d0
- bgt.s .end_calcxy
- move.w #-200,d0
- not.w .invertposx
- .end_calcxy:
- move.w distance+2(pc),d2
- addi.w #500,d2
- neg.w d2
- mulu.w objectvibr+2,d7
- swap d7
- add.w d7,d2
- cmpi.w #-100,d2
- blt.s .far_enough
- move.w #-100,d2
- .far_enough:
- movem.w d0-d2,-(sp)
- bsr TRANSFORM_OBJECT
- lea boundbox_tbl,a1
- lea .rot_tbl(pc),a2
- lea .rect_tbl(pc),a0
- bsr CALC_BOUNDINGWINDOW
- addq #6,sp
-
- * Finally paint everything on screen.
- ; lea .rot_tbl(pc),a1
- ; bsr PLOT_ROTATION
- bsr PLOT_OBJECT
-
- * Do timing and flipping of animationpages.
- lea .rect_tbl(pc),a0
- movem.l (a0),d0-d5
- movem.l d2-d5,(a0)
- movem.l d0-d1,4*4(a0)
- rts
-
- .rot_tbl:
- DC.W 0,0,0
- .rect_tbl:
- DS.W 4*3
- .peak: DC.W 0
- .inverse:
- DC.W 0
- .startrot:
- DC.W 0
- .start4bc:
- DC.W 0
- .lastrot:
- DC.W 0
- .leftvol:
- DC.W 0
- .rightvol:
- DC.W 0
- .objectposx:
- DC.W 0
- .invertposx:
- DC.W 0
-
- SET_ENVTORUS:
- move.l #torusobject_buf,envobjadr
-
- movea.l envobjadr,a1
- lea boundbox_tbl,a0
- bsr CALC_BOUNDINGBOX
- movea.l envobjadr,a1
- bsr INIT_OBJECT
- rts
-
- * Gets addresses of all tables in the 3d-object.
- * INPUT: a1: objectaddress (EARX envmapped format)
- INIT_OBJECT:
- move.w (a1)+,d0
- cmpi.w #maxpoints,d0
- move.w d0,d7
- mulu.w #pointsize,d0
- adda.l d0,a1
- move.l a1,pnttritbladr * address of pointtriangles
- move.w (a1)+,d0
- cmpi.w #maxtriangles,d0
- lea (a1,d0.w*trianglesize),a1
- move.w d0,d1
- move.l a1,edgestbladr * address of edges
- move.w (a1)+,d0
- cmpi.w #maxedges,d0
- lea (a1,d0.w*4),a1
- move.l a1,tritbladr * address of edgetriangles
- mulu.w #6,d1
- adda.l d1,a1
- move.l a1,normaltbladr * address of normals
-
- * Rescale normals.
- subq.w #1,d7
- .loop: movem.w (a1),d0-d2
- muls.w #$f0,d0
- muls.w #$f0,d1
- muls.w #$f0,d2
- asr.l #8,d0
- asr.l #8,d1
- asr.l #8,d2
- move.w d0,(a1)+
- move.w d1,(a1)+
- move.w d2,(a1)+
- dbra d7,.loop
- rts
-
- * Gets addresses of all tables in the 3d-object.
- * INPUT: a1: objectaddress (EARX envmapped format)
- INIT_OBJECT128:
- move.w (a1)+,d0
- move.w d0,d7
- mulu.w #pointsize,d0
- adda.l d0,a1
- move.l a1,pnttritbladr * address of pointtriangles
- move.w (a1)+,d0
- lea (a1,d0.w*trianglesize),a1
- move.w d0,d1
- move.l a1,edgestbladr * address of edges
- move.w (a1)+,d0
- lea (a1,d0.w*4),a1
- move.l a1,tritbladr * address of edgetriangles
- mulu.w #6,d1
- adda.l d1,a1
- move.l a1,normaltbladr * address of normals
-
- * Rescale normals for 128*128 texture.
- subq.w #1,d7
- .loop: movem.w (a1),d0-d2
- asr.w #1,d0
- asr.w #1,d1
- asr.w #1,d2
- move.w d0,(a1)+
- move.w d1,(a1)+
- move.w d2,(a1)+
- dbra d7,.loop
- rts
-
- * INPUT: a0: address of boundingbox-buffer to fill
- * a1: address of object's pointtable
- CALC_BOUNDINGBOX:
- * First find the highest and lowest x,y,z components..
- move.w (a1)+,d7
- move.w pointx(a1),d0
- move.w pointy(a1),d1
- move.w pointz(a1),d2
- move.w d0,d3
- move.w d1,d4
- move.w d2,d5
- subq.w #2,d7
- bmi.s .endloop
- lea pointsize(a1),a1
-
- .loop: move.w pointx(a1),d6
- cmp.w d6,d0
- ble.s .nonewxl
- move.w d6,d0
- .nonewxl:
- cmp.w d6,d3
- bge.s .nonewxh
- move.w d6,d3
- .nonewxh:
- move.w pointy(a1),d6
- cmp.w d6,d1
- ble.s .nonewyl
- move.w d6,d1
- .nonewyl:
- cmp.w d6,d4
- bge.s .nonewyh
- move.w d6,d4
- .nonewyh:
- move.w pointz(a1),d6
- cmp.w d6,d2
- ble.s .nonewzl
- move.w d6,d2
- .nonewzl:
- cmp.w d6,d5
- bge.s .nonewzh
- move.w d6,d5
- .nonewzh:
- lea pointsize(a1),a1
- dbra d7,.loop
- .endloop:
-
- * Now create a box (8 points) from the
- move.w d0,(a0)+ * / (xl,yl,zl)
- move.w d1,(a0)+ * |
- move.w d2,(a0)+ * \
- move.w d0,(a0)+ * / (xl,yl,zh)
- move.w d1,(a0)+ * |
- move.w d5,(a0)+ * \
- move.w d0,(a0)+ * / (xl,yh,zl)
- move.w d4,(a0)+ * |
- move.w d2,(a0)+ * \
- move.w d0,(a0)+ * / (xl,yh,zh)
- move.w d4,(a0)+ * |
- move.w d5,(a0)+ * \
- move.w d3,(a0)+ * / (xh,yl,zl)
- move.w d1,(a0)+ * |
- move.w d2,(a0)+ * \
- move.w d3,(a0)+ * / (xh,yl,zh)
- move.w d1,(a0)+ * |
- move.w d5,(a0)+ * \
- move.w d3,(a0)+ * / (xh,yh,zl)
- move.w d4,(a0)+ * |
- move.w d2,(a0)+ * \
- move.w d3,(a0)+ * / (xh,yh,zh)
- move.w d4,(a0)+ * |
- move.w d5,(a0)+ * \
- rts
-
- * INPUT: 8(sp).w: x center
- * 6(sp).w: y center
- * 4(sp).w: z center
- * a0: address of rectangleinfo
- * a1: address of boundingbox structure
- * a2: address of rotationtable
- CALC_BOUNDINGWINDOW:
- movea.l a0,a5 * Backup rectinfo address.
- * Get sine-values..
- lea sine_tbl,a3
- move.w (a2)+,d0
- Do_SinModulo d0
- Get_SinCos a3,d0,d1,d2
- move.w (a2)+,d0
- Do_SinModulo d0
- Get_SinCos a3,d0,d3,d4
-
- lea .box_tbl(pc),a0
- movea.l a1,a2
- movea.l a0,a6
-
- * Calculate the x-coordinates..
- moveq #8-1,d7
- .xloop move.w (a1),d0
- muls.w d4,d0
- addq #4,a1
- move.w (a1)+,d5
- muls.w d3,d5
- sub.l d5,d0
- add.l d0,d0
- swap d0
- move.w d0,(a0)
- addq #6,a0
- dbra d7,.xloop
-
- * Calculate the y-coordinates..
- lea 2(a6),a0 * Get address of first y-coord
- move.l d3,a3 * Backup
- move.l d4,a4 * Backup
- muls.w d1,d3
- muls.w d1,d4
- subq.l #1,d3
- subq.l #1,d4
- add.l d3,d3
- add.l d4,d4
- swap d3
- swap d4
- move.l a2,a1
- moveq #8-1,d7
- .yloop: movem.w (a1)+,d5-d6
- muls.w d3,d5
- muls.w d2,d6
- move.w (a1)+,d0
- muls.w d4,d0
- add.l d0,d5
- add.l d6,d5
- add.l d5,d5
- swap d5
- move.w d5,(a0)
- addq #6,a0
- dbra d7,.yloop
-
- * Calculate the z-coordinates..
- lea 4(a6),a0 * Get address of first z-coord
- move.l a3,d3
- move.l a4,d4
- muls.w d2,d3
- muls.w d2,d4
- subq.l #1,d3
- subq.l #1,d4
- add.l d3,d3
- add.l d4,d4
- swap d3
- swap d4
- move.l a2,a1
- moveq #8-1,d7
- .zloop: movem.w (a1)+,d5-d6
- muls.w d3,d5
- muls.w d1,d6
- sub.l d6,d5
- move.w (a1)+,d0
- muls.w d4,d0
- add.l d0,d5
- add.l d5,d5
- swap d5
- move.w d5,(a0)
- addq #6,a0
- dbra d7,.zloop
-
- * Perspectivate the points.
- movea.l a5,a0
- movem.w 4(sp),a3-a5 * Get center-coordinates.
- move.l a0,-(sp) * Backup rectangleaddress.
- movea.l a6,a0
- moveq #8-2,d7
- move.w #scrxbytes/4,d3
- move.w #envmapyres/2,d4
- move.w #$0100,d5
- sub.w a5,d5
- move.w #310,d6
-
- movem.w (a0)+,d1-d2
- move.w (a0)+,d0
- neg.w d0
- add.w d5,d0 * d0.w: scalefactor
- add.l a3,d1
- add.l a4,d2
- lsl.l #8,d1
- muls.w d6,d2
- divs.w d0,d1 * Scale x-coordinate.
- divs.w d0,d2 * Scale y-coordinate.
- add.w d3,d1 * Center x-coordinate.
- add.w d4,d2 * Center y-coordinate.
- movea.w d1,a1
- movea.w d2,a2
- movea.w d1,a5
- movea.w d2,a6
-
- .loop: movem.w (a0)+,d1-d2
- move.w (a0)+,d0
- neg.w d0
- add.w d5,d0 * d0.w: scalefactor
- add.l a3,d1
- add.l a4,d2
- lsl.l #8,d1
- muls.w d6,d2
- divs.w d0,d1 * Scale x-coordinate.
- divs.w d0,d2 * Scale y-coordinate.
- add.w d3,d1 * Center x-coordinate.
- add.w d4,d2 * Center y-coordinate.
- cmpa.w d1,a1
- ble.s .nonewxl
- movea.w d1,a1
- bra.s .endcmpx
- .nonewxl:
- cmpa.w d1,a5
- bge.s .nonewxh
- movea.w d1,a5
- .nonewxh:
- .endcmpx:
- cmpa.w d2,a2
- ble.s .nonewyl
- movea.w d2,a2
- bra.s .endcmpy
- .nonewyl:
- cmpa.w d2,a6
- bge.s .nonewyh
- movea.w d2,a6
- .nonewyh:
- .endcmpy:
- dbra d7,.loop
-
- movea.l (sp)+,a0 * Get rectangleaddress.
- subq #1,a1 * / Make clearwindow
- subq #1,a2 * \ a bit wider.
- addq #1,a5
- addq #1,a6
- movem.w a1-a2/a5-a6,(a0) * Store rectangle.
- rts
-
- .box_tbl:
- DS.W 8*3
-
- * INPUT: d0.w: left x
- * d1.w: upper y
- * d2.w: right x
- * d3.w: lower y
- CLEAR_RECTANGLE:
- tst.w d0
- bpl.s .testx0
- moveq #0,d0
- .testx0:
- cmpi.w #envmapxres,d0
- blt.s .endtestx0
- move.w #envmapxres-1,d0
- .endtestx0:
-
- tst.w d1
- bpl.s .testy0
- moveq #0,d1
- .testy0:
- cmpi.w #envmapyres,d1
- blt.s .endtesty0
- move.w #envmapyres-1,d1
- .endtesty0:
-
- tst.w d6
- bgt.s .testx1
- moveq #0,d6
- .testx1:
- cmpi.w #envmapxres,d6
- blt.s .endtestx1
- move.w #envmapxres-1,d6
- .endtestx1:
-
- tst.w d7
- bgt.s .testy1
- moveq #0,d7
- .testy1:
- cmpi.w #envmapyres,d7
- blt.s .endtesty1
- move.w #envmapyres-1,d7
- .endtesty1:
-
- movea.l scr,a0
- move.w d6,d2
- move.w d7,d3
- addq.w #1,d2
- andi.w #$fffe,d2
- adda.w d2,a0
- adda.w d2,a0
- mulu.w #scrxbytes,d3
- adda.l d3,a0
- sub.w d0,d6
- addq.w #1,d6
- sub.w d1,d7
- moveq #$00000000,d0
- move.l d0,d1
- move.l d0,d2
- move.l d0,d3
- move.l d0,d4
- movea.l d0,a1
- movea.l d0,a2
- movea.l d0,a3
- movea.w #scrxbytes,a4
- lsr.w #1,d6
- move.w d6,d5
- add.w d6,d5
- add.w d5,d5
- suba.w d5,a4
- ext.l d6
- move.l d6,d5
- andi.w #$0007,d6
- lsr.w #3,d5
- neg.l d5
- neg.l d6
- lea (.endchunks.w,pc,d5.l*4),a5
- lea (.endpix.w,pc,d6.l*2),a6
-
- .yloop: jmp (a5)
- REPT envmapxres/16
- movem.l d0-d4/a1-a3,-(a0)
- ENDR
- .endchunks:
- jmp (a6)
- REPT 7
- move.l d0,-(a0)
- ENDR
- .endpix:
-
- suba.l a4,a0
- dbra d7,.yloop
- rts
-
- * INPUT: d0.w: left x
- * d1.w: upper y
- * d2.w: right x
- * d3.w: lower y
- CLEAR_RECTANGLEDBL:
- tst.w d0
- bpl.s .testx0
- moveq #0,d0
- .testx0:
- cmpi.w #envmapxres,d0
- blt.s .endtestx0
- move.w #envmapxres-1,d0
- .endtestx0:
-
- tst.w d1
- bpl.s .testy0
- moveq #0,d1
- .testy0:
- cmpi.w #100,d1
- blt.s .endtesty0
- move.w #100-1,d1
- .endtesty0:
-
- tst.w d6
- bgt.s .testx1
- moveq #0,d6
- .testx1:
- cmpi.w #envmapxres,d6
- blt.s .endtestx1
- move.w #envmapxres,d6
- .endtestx1:
-
- tst.w d7
- bgt.s .testy1
- moveq #0,d7
- .testy1:
- cmpi.w #100,d7
- blt.s .endtesty1
- move.w #100-1,d7
- .endtesty1:
-
- add.w d0,d0
- add.w d6,d6
- movea.l scr,a0
- move.w d6,d2
- move.w d7,d3
- adda.w d2,a0
- adda.w d2,a0
- mulu.w #scrxbytes,d3
- adda.l d3,a0
- sub.w d0,d6
- addq.w #1,d6
- sub.w d1,d7
- moveq #$00000000,d0
- move.l d0,d1
- move.l d0,d2
- move.l d0,d3
- move.l d0,d4
- movea.l d0,a1
- movea.l d0,a2
- movea.l d0,a3
- movea.w #scrxbytes,a4
- lsr.w #1,d6
- move.w d6,d5
- add.w d6,d5
- add.w d5,d5
- suba.w d5,a4
- ext.l d6
- move.l d6,d5
- andi.w #$0007,d6
- lsr.w #3,d5
- neg.l d5
- neg.l d6
- add.l d5,d5
- add.l d5,d5
- add.l d6,d6
- lea (.endchunks.b,pc,d5.l),a5
- lea (.endpix.b,pc,d6.l),a6
-
- .yloop:
-
- .xloop:
- jmp (a5)
- REPT scrxbytes/32
- movem.l d0-d4/a1-a3,-(a0)
- ENDR
- .endchunks:
- jmp (a6)
- REPT 7
- move.l d0,-(a0)
- ENDR
- .endpix:
-
- suba.l a4,a0
- dbra d7,.yloop
- rts
-
- * INPUT: a1: address of rotationtable
- PLOT_ROTATION:
- movea.l scr,a0
- move.w (a1)+,d7
- Do_SinModulo d7
- mulu.w #((1<<16)*envmapxres)/sintbllen,d7
- swap d7
- move.w d7,d6
- subq.w #1,d7
- bmi.s .endplotx
-
- .loop: move.w #$f800,(a0)+
- dbra d7,.loop
-
- move.w #envmapxres-1,d7
- sub.w d6,d7
- bmi.s .skipclr1
- moveq #0,d0
- .clrloop1:
- move.w d0,(a0)+
- dbra d7,.clrloop1
- .skipclr1:
- .endplotx:
-
- movea.l scr,a0
- adda.l #envmapxres*2*2,a0
- move.w (a1)+,d7
- Do_SinModulo d7
- mulu.w #((1<<16)*envmapxres)/sintbllen,d7
- swap d7
- move.w d7,d6
- subq.w #1,d7
- bmi.s .endploty
-
- .loop2: move.w #$03c0,(a0)+
- dbra d7,.loop2
- .endloop2:
-
- move.w #envmapxres-1,d7
- sub.w d6,d7
- bmi.s .skipclr2
- moveq #0,d0
- .clrloop2:
- move.w d0,(a0)+
- dbra d7,.clrloop2
- .skipclr2:
- .endploty:
- rts
-
- * This routine is just a easy to calculate sinus-matrix thingy
- * rotates around the x-axis and then around the y-axis.
- * makes a rotated copy of the original...
- * INPUT: a1: address of source objectbuffer
- * a2: address of rotation-array
- ROTATE_OBJECT:
- * Get sine-values..
- lea sine_tbl,a0
- move.w (a2)+,d0
- Do_SinModulo d0
- Get_SinCos a0,d0,d1,d2
- move.w (a2)+,d0
- Do_SinModulo d0
- Get_SinCos a0,d0,d3,d4
- lea points_tbl,a0
- move.w (a1)+,d7
- move.w d7,(a0)+
- subq.w #1,d7
- movea.w d7,a5
- movea.l a1,a2
- movea.l a0,a6
-
- * Calculate the x-coordinates..
- .xloop move.w (a1),d0
- muls.w d4,d0
- addq #pointz,a1
- move.w (a1)+,d5
- muls.w d3,d5
- sub.l d5,d0
- add.l d0,d0
- swap d0
- move.w d0,(a0)
- lea pointsize(a0),a0
- dbra d7,.xloop
-
- * Calculate the texture x-coordinates..
- lea pointtx(a6),a0 * Get address of first texture x-coord
- movea.l normaltbladr,a1
- move.w a5,d7
- IFNE envlightrot
- .normxloop:
- move.w (a1)+,d0
- muls.w d4,d0
- addq #2,a1
- move.w (a1)+,d5
- muls.w d3,d5
- sub.l d5,d0
- swap d0
- move.w d0,(a0)
- lea pointsize(a0),a0
- dbra d7,.normxloop
- ELSE
- .normxloop:
- move.w (a1),(a0)
- addq #6,a1
- lea pointsize(a0),a0
- dbra d7,.normxloop
- ENDC
-
- * Calculate the y-coordinates..
- lea pointy(a6),a0 * Get address of first y-coord
- move.l d3,a3 * Backup
- move.l d4,a4 * Backup
- muls.w d1,d3
- muls.w d1,d4
- subq.l #1,d3
- subq.l #1,d4
- add.l d3,d3
- add.l d4,d4
- swap d3
- swap d4
- move.l a2,a1
- move.w a5,d7
- .yloop: movem.w (a1),d5-d6
- muls.w d3,d5
- muls.w d2,d6
- addq #pointz,a1
- move.w (a1)+,d0
- muls.w d4,d0
- add.l d0,d5
- add.l d6,d5
- add.l d5,d5
- swap d5
- move.w d5,(a0)
- lea pointsize(a0),a0
- dbra d7,.yloop
-
- * Calculate the texture y-coordinates..
- lea pointty(a6),a0 * Get address of first texture y-coord
- movea.l normaltbladr,a1
- move.w a5,d7
- IFNE envlightrot
- .normyloop:
- movem.w (a1)+,d5-d6
- muls.w d3,d5
- muls.w d2,d6
- move.w (a1)+,d0
- muls.w d4,d0
- add.l d0,d5
- add.l d6,d5
- swap d5
- move.w d5,(a0)
- lea pointsize(a0),a0
- dbra d7,.normyloop
- ELSE
- addq #2,a1
- .normyloop:
- move.w (a1),(a0)
- addq #6,a1
- lea pointsize(a0),a0
- dbra d7,.normyloop
- ENDC
-
- * Calculate the z-coordinates..
- lea pointz(a6),a0 * Get address of first z-coord
- move.l a3,d3
- move.l a4,d4
- muls.w d2,d3
- muls.w d2,d4
- subq.l #1,d3
- subq.l #1,d4
- add.l d3,d3
- add.l d4,d4
- swap d3
- swap d4
- move.l a2,a1
- move.w a5,d7
- .zloop: movem.w (a1),d5-d6
- muls.w d3,d5
- muls.w d1,d6
- sub.l d6,d5
- addq #pointz,a1
- move.w (a1)+,d0
- muls.w d4,d0
- add.l d0,d5
- add.l d5,d5
- swap d5
- move.w d5,(a0)
- lea pointsize(a0),a0
- dbra d7,.zloop
- rts
-
- * Adds x, y, z values to each of the points in the object and
- * transforms 3d -> 2d.
- * INPUT: d0.w: x-offset
- * d1.w: y-offset
- * d2.w: z-offset
- TRANSFORM_OBJECT:
- lea points_tbl,a0
- move.w (a0)+,d7
- subq.w #1,d7
-
- move.w #scrxbytes/4,d3
- move.w #envmapyres/2,d4
- movea.w d0,a3
- movea.w d1,a4
- move.w #$0100,d5
- sub.w d2,d5
- move.w #310,d6
-
- .loop: move.w pointz(a0),d0
- neg.w d0
- add.w d5,d0 * d0.w: scale factor
- movem.w (a0),d1-d2
- add.l a3,d1
- add.l a4,d2
- lsl.l #8,d1
- muls.w d6,d2
- divs.w d0,d1 * Scale x-coordinate.
- divs.w d0,d2 * Scale y-coordinate.
- add.w d3,d1 * Center x-coordinate.
- add.w d4,d2 * Center y-coordinate.
- move.w d1,(a0)+
- move.w d2,(a0)+
- addq #pointsize-4,a0
- dbra d7,.loop
- rts
-
- * Plots one environment mapped object. Backface culling and painters
- * algorithm depthsorting are used.
- * The object plotting is only suited to objects that have a texture mapped
- * around them. That is: only one texturebitmap.
- PLOT_OBJECT:
- * STEP 0:
- * Set all edges to unused..
- moveq #0,d0
- lea .edgesdone_tbl,a0
- movea.l edgestbladr,a1
- move.w (a1),d7
- lsr.w #2,d7
- .clredgesdoneloop:
- move.l d0,(a0)+
- dbra d7,.clredgesdoneloop
-
- * STEP 1:
- * Put all Z-points of triangles in the sorting table and kick out backface
- * triangles. Also mark the used edges.
- .putsortvals:
- movea.l pnttritbladr,a5
- move.w (a5)+,d7
- subq.w #1,d7
- bmi .rts
- moveq #0,d0
- lea points_tbl+2,a3
- lea .sort_tbl+2,a6
- movea.l tritbladr,a1
- lea .edgesdone_tbl,a2
-
- .putsortvalsloop:
- move.w (a5)+,d6
- mulu.w #pointsize,d6
- movea.w pointz(a3,d6.l),a4
- movem.w (a3,d6.l),d1-d2
- move.w (a5)+,d6
- mulu.w #pointsize,d6
- adda.w pointz(a3,d6.l),a4
- movem.w (a3,d6.l),d3-d4
- move.w (a5)+,d6
- mulu.w #pointsize,d6
- adda.w pointz(a3,d6.l),a4
- movem.w (a3,d6.l),d5-d6
-
- sub.w d3,d1
- sub.w d3,d5
- sub.w d4,d2
- sub.w d4,d6
- muls.w d1,d6
- muls.w d2,d5
- cmp.l d6,d5
- bgt.s .visible
- addq #6,a1
- bra.s .endputsortvalsloop
- .visible:
- addq.w #1,d0 * Increase number of visible triangles.
- move.w a4,(a6)+ * Store Z-center of triangle in sortingtable.
- move.l a1,(a6)+ * Store address of triangle.
- movem.w (a1)+,d1-d3 * Get edgenumbers.
- moveq #1,d4
- move.b d4,(a2,d1.l) * Mark edge 0 as visible.
- move.b d4,(a2,d2.l) * Mark edge 1 as visible.
- move.b d4,(a2,d3.l) * mark edge 2 as visible.
- .endputsortvalsloop:
- addq #trianglesize-triangleinfo,a5
- dbra d7,.putsortvalsloop
- move.w d0,.sort_tbl * Store number of visible triangles.
-
- * STEP 2:
- * Calculate all the visible edges into nice edgetables.
- .calcedges:
- lea temp_buf,a4
- lea .edgesdone_tbl,a3
- movea.l edgestbladr,a2
- move.w (a2)+,d7
- subq.w #1,d7
- bmi .rts
- lea points_tbl+2,a1
- lea 2*2*maxedges(a4),a0
- movea.l a0,a6
-
- .calcedgeloop:
- move.w d7,-(sp)
-
- tst.b (a3)+
- beq.s .dontcalcedge
-
- move.l a0,(a4)+
-
- move.w (a2)+,d0
- move.w (a2)+,d4
-
- mulu.w #pointsize,d0
- mulu.w #pointsize,d4
- movem.w (a1,d0.l),d0-d3
- movem.w (a1,d4.l),d4-d7
- bsr CALCULATE_EDGETABLE
- bra.s .calcedgeloopend
-
- .dontcalcedge:
- addq #4,a4
- addq #4,a2
-
- .calcedgeloopend:
- move.w (sp)+,d7
- dbra d7,.calcedgeloop
-
- * STEP 3:
- * Now sort all the visible triangles using combsort.
- * Combsort rules!! Thanx to Dynacore/.tSCc. for his great article!
- lea .sort_tbl,a1
- move.w (a1)+,d7 * d7.w: number of triangles
- subq.w #1,d7
- beq.s .endcombsort
- bmi .rts
- movea.l a1,a3
- move.w d7,d4
- lsr.w #1,d4 * d4.w: gapsize
- bra.s .endcalcgap
- .combsortloop:
- cmpi.w #2,d4 * / If the gapsize
- bhi.s .calcgap * | is already 1 or
- moveq #1,d4 * | 2 then always
- bra.s .endcalcgap * \ set it to 1.
- .calcgap:
- mulu.w #((1<<16)*10)/13,d4 * / Resize
- swap d4 * \ the gap.
- .endcalcgap:
- move.w d7,d6
- sub.w d4,d6
- move.w d4,d0
- mulu.w #2+4,d0
- lea (a3,d0.l),a5
- moveq #0,d5 * d5.w: number of swaps done in loop
-
- .combsortinloop:
- move.w (a1),d0
- move.w (a5),d1
- cmp.w d1,d0
- ble.s .noswap
- move.w d1,(a1)+ * / Swap
- move.w d0,(a5)+ * \ depth.
- move.l (a1),d0 * / Swap the
- move.l (a5),(a1)+ * | triangle
- move.l d0,(a5)+ * \ addresses.
- addq.w #1,d5
- dbra d6,.combsortinloop
- bra.s .combsortloopend
- .noswap:
- addq #6,a1
- addq #6,a5
- dbra d6,.combsortinloop
- .combsortloopend:
- movea.l a3,a1
- move.w d5,d5
- bne.s .combsortloop
- cmpi.w #1,d4
- bne.s .combsortloop
- .endcombsort:
-
- * STEP 4:
- * Plot all the visible triangles in their Z-order.
- lea .sort_tbl,a1
- move.w (a1)+,d7
- subq.w #1,d7
- bmi.s .rts
- lea temp_buf,a2
- movea.l envtextureadr,a3
- adda.l #(256*2*128)+128*2,a3
-
- .plottriangleloop:
- move.w d7,-(sp)
-
- addq #2,a1
- movea.l (a1)+,a0
- movem.w (a0),d0-d2
- movem.l a1-a3,-(sp)
- bsr PLOT_ENVMAPTRIANGLE
- movem.l (sp)+,a1-a3
-
- move.w (sp)+,d7
- dbra d7,.plottriangleloop
-
- .rts: rts
-
- .edgesdone_tbl:
- DS.B maxedges
- .sort_tbl:
- DS.W 3*maxtriangles
-
- ; lsl.l #6,d4
- ; movea.l d4,a6
- ; adda.l a6,a6
- ; adda.l d4,a6
- ; adda.l d5,a6
- ; move.l (a5,a6.l),d4
-
- * Calculates all scanline points of the edges and puts them in a table.
- * This should also take care of horizontal clipping and of onscreen
- * detection.
- * INPUT: d0.l: X-start
- * d1.l: Y-start
- * d2.l: TX-start
- * d3.l: TY-start
- * d4.l: X-end
- * d5.l: Y-end
- * d6.l: TX-end
- * d7.l: TY-end
- * a0: address to write new edgetable to
- * OUTPUT: a0: address of next edgetable
- CALCULATE_EDGETABLE:
- cmp.w d5,d1
- bgt.s .domirrored
-
- beq.s .emptyedge
- sub.l d1,d5
- move.w d5,(a0)+
- move.w d1,(a0)+
- swap d0
- swap d4
- sub.w d0,d0
- sub.w d4,d4
- sub.l d0,d4
- lsl.l #8,d2
- lsl.l #8,d3
- lsl.l #8,d6
- lsl.l #8,d7
- sub.l d2,d6
- sub.l d3,d7
- divs.w d5,d6
- divs.w d5,d7
- divs.l d5,d4
- move.l d4,(a0)+
- .loop: move.l d0,d1
- swap d1
- move.w d1,(a0)+
- move.w d2,(a0)+
- move.w d3,(a0)+
- add.l d4,d0
- add.w d6,d2
- add.w d7,d3
- dbra d5,.loop
- rts
- * Edge is completely horizontal, so it doesn't need to be drawn.
- .emptyedge:
- clr.w (a0)+
- move.w d1,(a0)+
- addq #edgeheadersize-4,a0
- rts
-
- * Y-start is larger than Y-end, so do everything the other way round.
- .domirrored:
- sub.l d5,d1
- beq.s .mirroremptyedge
- move.w d1,(a0)+
- move.w d5,(a0)+
- swap d4
- swap d0
- sub.w d4,d4
- sub.w d0,d0
- sub.l d4,d0
- lsl.l #8,d6
- lsl.l #8,d7
- lsl.l #8,d2
- lsl.l #8,d3
- sub.l d6,d2
- sub.l d7,d3
- divs.w d1,d2
- divs.w d1,d3
- divs.l d1,d0
- move.l d0,(a0)+
- .mirrorloop:
- move.l d4,d5
- swap d5
- move.w d5,(a0)+
- move.w d6,(a0)+
- move.w d7,(a0)+
- add.l d0,d4
- add.w d2,d6
- add.w d3,d7
- dbra d1,.mirrorloop
- rts
- * Edge is completely horizontal, so it doesn't need to be drawn.
- .mirroremptyedge:
- clr.w (a0)+
- move.w d5,(a0)+
- addq #edgeheadersize-4,a0
- rts
-
- * Plots a texturemapped triangle using the specified edgetables.
- * Does not do clipping whatsoever. The clipping of an object needs
- * to be done by the routine that handles edge-calculations and the
- * one that handles culling and sorting.
- * INPUT: d0.l: edge index 1
- * d1.l: edge index 2
- * d2.l: edge index 3
- * a2: address of edgetable-buffer
- * a3: address of middle of texture (256*256 highcolor)
- PLOT_ENVMAPTRIANGLE:
- move.l a3,.textureadr
- movea.l (a2,d0.l*4),a4
- movea.l (a2,d1.l*4),a5
- movea.l (a2,d2.l*4),a6
-
- * Find out which two edges are first and which one is second.
- .order: move.w edgestarty(a4),d0
- move.w edgestarty(a5),d1
- move.w edgestarty(a6),d2
- cmp.w d0,d1
- beq.s .endorder
- cmp.w d0,d2
- bne.s .1_2
- exg a6,a5
- exg d2,d1
- bra.s .endorder
- .1_2: exg a6,a4
- exg d2,d0
- .endorder:
-
- * Test if all edges start are first => triangle is a dot/scanline or a \/
- .testspecial:
- cmp.w d0,d2
- bne .calcnormalslope
- tst.w (a4)
- bne.s .testa5
- exg a4,a6
- bra.s .testscan
- .testa5:
- tst.w (a5)
- bne.s .testscan
- exg a5,a6
- * Test if the triangle is a dot/scanline
- .testscan:
- tst.w (a4)
- bne.s .specialslope
- tst.w (a5)
- bne.s .specialslope
- tst.w (a6)
- bne.s .specialslope
- rts
-
- * Calculate slope-offset table for special \/ case.
- .specialslope:
- lea .textureoffset_tbl(pc),a1
- movem.w edgeheadersize(a4),d0-d2
- movem.w edgeheadersize(a5),d3-d5
- sub.w d0,d3
- beq .endscanplot
- sub.l d1,d4
- sub.l d2,d5
- divs.w d3,d4
- divs.w d3,d5
- move.w d3,d3
- bpl.s .d3pos
- neg.w d3
- .d3pos: addq.w #1,d3
- moveq #0,d1
- moveq #0,d2
- lsl.l #8,d4
- swap d5
- move.w d4,d5
- swap d5
- swap d4
- .specialcalcslopeloop:
- move.w d2,d0
- move.b d1,d0
- move.w d0,(a1)+
- add.l d5,d2
- addx.b d4,d1
- dbra d3,.specialcalcslopeloop
- * Find out which edges are left and which are right.
- move.w edgeheadersize(a5),d0
- cmp.w edgeheadersize(a4),d0
- bge.s .plot
- exg a4,a5
- bra.s .plot
-
- * Calculate slope-offset table for normal case.
- .calcnormalslope:
- lea .textureoffset_tbl(pc),a1
- move.w (a4),d6
- move.w (a5),d1
- cmp.w d1,d6
- ble.s .d6smaller
- move.w d1,d6
- .d6smaller:
- mulu.w #6,d6
- movem.w edgeheadersize(a4,d6.l),d0-d2
- movem.w edgeheadersize(a5,d6.l),d3-d5
- sub.w d0,d3
- beq .endscanplot
- sub.l d1,d4
- sub.l d2,d5
- divs.w d3,d4
- divs.w d3,d5
- moveq #0,d1
- moveq #0,d2
- move.w d3,d3
- bpl.s .normlengthpos
- neg.w d3
- .normlengthpos:
- addq.w #1,d3
- lsl.l #8,d4
- swap d5
- move.w d4,d5
- swap d5
- swap d4
- .normalcalcslopeloop:
- move.w d2,d0
- move.b d1,d0
- move.w d0,(a1)+
- add.l d5,d2
- addx.b d4,d1
- dbra d3,.normalcalcslopeloop
- * Find out which edges are left and which are right..
- .leftright:
- move.l edgeslope(a5),d0
- cmp.l edgeslope(a4),d0
- bge.s .noswap
- exg a4,a5
- .noswap:
-
- * Prepare for plotting in the screenbuffer.
- .plot:
- .initplot:
- moveq #0,d6
- move.w (a4),d5
- move.w (a5),d6
- sub.w d5,d6
- bgt.s .endinitplot
- neg.w d6
- move.w (a5),d5
- bset #31,d6 * Edge in a4 is longest.
- .endinitplot:
-
- movea.l scr,a3
- move.l .textureadr(pc),d7
- move.l #.textureoffset_tbl,d4
-
- .yclip:
- move.w edgestarty(a4),d0
- bpl.s .noylowclip
- add.w d0,d5
- ble.s .noplotfirst
- neg.w d0
- mulu.w #6,d0
- adda.l d0,a4
- adda.l d0,a5
- moveq #0,d0
- bra.s .endyclip
- .noplotfirst:
- add.w d5,d6
- ble .rts
- neg.w d0
- neg.w d5
- mulu.w #6,d0
- mulu.w #6,d5
- lea edgeheadersize(a4,d0.l),a4
- lea edgeheadersize(a5,d0.l),a5
- adda.l d5,a6
- bra .plotsecond
- .noylowclip:
- cmpi.w #envmapyres,d0
- bge .rts
- move.w d6,d1
- add.w d5,d1
- add.w d0,d1
- bmi .rts
- subi.w #envmapyres,d1
- bmi.s .endyclip
- sub.w d1,d6
- bpl.s .endyclip
- add.w d6,d5
- .endyclip:
-
- .plotfirst:
- mulu.w #scrxbytes,d0
- addq #edgeheadersize,a4
- addq #edgeheadersize,a5
- adda.l d0,a3
- subq.w #1,d5
- * Plot upper part of triangle.
- .firstloop:
- movea.l d4,a2
- move.w (a5),d3
- addq #6,a5
- movem.w (a4)+,d0-d2
-
- movea.l d7,a1
- lsr.w #8,d1
- move.b d1,d2
- lea (a1,d2.l*2),a1
-
- move.l d0,d1
- bpl.s .xpos1
- neg.l d1
- lea (a2,d1.l*2),a2
- moveq #0,d0
- .xpos1: lea (a3,d0.l*2),a0
- cmpi.w #envmapxres,d3
- blt.s .nottoobig
- move.w d3,d2
- subi.w #envmapxres-1,d2
- sub.w d2,d3
- .nottoobig:
- sub.w d0,d3
- bmi.s .endfirstline
-
- .pixelloop:
- move.w (a2)+,d1
- move.w (a1,d1.w*2),(a0)+
- dbra d3,.pixelloop
-
- .endfirstline:
- lea scrxbytes(a3),a3
- dbra d5,.firstloop
- .endplotfirst:
-
- * Plot lower part of triangle..
- .plotsecond:
- subq.w #1,d6
- bmi.s .endsecond * Triangle is a /\ or a \/
- * Test if left or right was shorter..
- btst #31,d6 * Which edge is longest?
- bne.s .noswaplr
- lea edgeheadersize(a6),a4
- move.w d6,d5
- sub.w d6,d6
- bra .firstloop
-
- .noswaplr:
- move.w d6,d5
- sub.w d6,d6
- lea edgeheadersize(a6),a5
- bra .firstloop
-
- .endsecond:
-
- .endscanplot:
-
- .rts: rts
-
- .edgestartadr:
- DS.L 1
- .textureadr:
- DS.L 1
- .textureoffset_tbl:
- DS.W scrxbytes/2
-
- * Plots a texturemapped triangle using the specified edgetables.
- * Does not do clipping whatsoever. The clipping of an object needs
- * to be done by the routine that handles edge-calculations and the
- * one that handles culling and sorting.
- * INPUT: d0.l: edge index 1
- * d1.l: edge index 2
- * d2.l: edge index 3
- * a2: address of edgetable-buffer
- * a3: address of middle of texture (128*128 highcolor)
- PLOT_MAPTRIANGLE128:
- move.l a3,.textureadr
- movea.l (a2,d0.l*4),a4
- movea.l (a2,d1.l*4),a5
- movea.l (a2,d2.l*4),a6
-
- * Find out which two edges are first and which one is second.
- .order: move.w edgestarty(a4),d0
- move.w edgestarty(a5),d1
- move.w edgestarty(a6),d2
- cmp.w d0,d1
- beq.s .endorder
- cmp.w d0,d2
- bne.s .1_2
- exg a6,a5
- exg d2,d1
- bra.s .endorder
- .1_2: exg a6,a4
- exg d2,d0
- .endorder:
-
- * Test if all edges start are first => triangle is a dot/scanline or a \/
- .testspecial:
- cmp.w d0,d2
- bne .calcnormalslope
- tst.w (a4)
- bne.s .testa5
- exg a4,a6
- bra.s .testscan
- .testa5:
- tst.w (a5)
- bne.s .testscan
- exg a5,a6
- * Test if the triangle is a dot/scanline
- .testscan:
- tst.w (a4)
- bne.s .specialslope
- tst.w (a5)
- bne.s .specialslope
- tst.w (a6)
- bne.s .specialslope
- rts
-
- * Calculate slope-offset table for special \/ case.
- .specialslope:
- lea .textureoffset_tbl(pc),a1
- movem.w edgeheadersize(a4),d0-d2
- movem.w edgeheadersize(a5),d3-d5
- sub.w d0,d3
- beq .endscanplot
- sub.l d1,d4
- sub.l d2,d5
- divs.w d3,d4
- divs.w d3,d5
- move.w d3,d3
- bpl.s .d3pos
- neg.w d3
- .d3pos: moveq #0,d1
- moveq #0,d2
- lsl.l #8,d4
- swap d5
- move.w d4,d5
- swap d5
- swap d4
- addq.w #1,d3
- .specialcalcslopeloop:
- move.w d2,d0
- sub.b d0,d0
- add.b d1,d0
- add.b d0,d0
- add.w d0,d0
- move.w d0,(a1)+
- add.l d5,d2
- addx.b d4,d1
- dbra d3,.specialcalcslopeloop
- * Find out which edges are left and which are right.
- move.w edgeheadersize(a5),d0
- cmp.w edgeheadersize(a4),d0
- bge.s .plot
- exg a4,a5
- bra.s .plot
-
- * Calculate slope-offset table for normal case.
- .calcnormalslope:
- lea .textureoffset_tbl(pc),a1
- move.w (a4),d6
- move.w (a5),d1
- cmp.w d1,d6
- ble.s .d6smaller
- move.w d1,d6
- .d6smaller:
- mulu.w #6,d6
- movem.w edgeheadersize(a4,d6.l),d0-d2
- movem.w edgeheadersize(a5,d6.l),d3-d5
- sub.w d0,d3
- beq .endscanplot
- sub.l d1,d4
- sub.l d2,d5
- divs.w d3,d4
- divs.w d3,d5
- moveq #0,d1
- moveq #0,d2
- move.w d3,d3
- bpl.s .normlengthpos
- neg.w d3
- .normlengthpos:
- lsl.l #8,d4
- swap d5
- move.w d4,d5
- swap d5
- swap d4
- addq.w #1,d3
- .normalcalcslopeloop:
- move.w d2,d0
- sub.b d0,d0
- add.b d1,d0
- add.b d0,d0
- add.w d0,d0
- move.w d0,(a1)+
- add.l d5,d2
- addx.b d4,d1
- dbra d3,.normalcalcslopeloop
- * Find out which edges are left and which are right..
- .leftright:
- move.l edgeslope(a5),d0
- cmp.l edgeslope(a4),d0
- bge.s .noswap
- exg a4,a5
- .noswap:
-
- * Prepare for plotting in the screenbuffer.
- .plot:
- .initplot:
- moveq #0,d6
- move.w (a4),d5
- move.w (a5),d6
- sub.w d5,d6
- bgt.s .endinitplot
- neg.w d6
- move.w (a5),d5
- bset #31,d6 * Edge in a4 is longest.
- .endinitplot:
-
- movea.l scr,a3
- move.l .textureadr(pc),d7
- move.l #.textureoffset_tbl,d4
-
- .yclip: move.w edgestarty(a4),d0
- bpl.s .noylowclip
- add.w d0,d5
- ble.s .noplotfirst
- neg.w d0
- mulu.w #6,d0
- adda.l d0,a4
- adda.l d0,a5
- moveq #0,d0
- bra.s .endyclip
- .noplotfirst:
- add.w d5,d6
- ble .rts
- neg.w d0
- neg.w d5
- mulu.w #6,d0
- mulu.w #6,d5
- lea edgeheadersize(a4,d0.l),a4
- lea edgeheadersize(a5,d0.l),a5
- adda.l d5,a6
- bra .plotsecond
- .noylowclip:
- cmpi.w #envmapyres,d0
- bge .rts
- move.w d6,d1
- add.w d5,d1
- add.w d0,d1
- bmi .rts
- subi.w #envmapyres,d1
- bmi.s .endyclip
- sub.w d1,d6
- bpl.s .endyclip
- add.w d6,d5
- .endyclip:
-
- .plotfirst:
- mulu.w #scrxbytes,d0
- addq #edgeheadersize,a4
- addq #edgeheadersize,a5
- adda.l d0,a3
- subq.w #1,d5
- * Plot upper part of triangle.
- .firstloop:
- movea.l d4,a2
- move.w (a5),d3
- addq #6,a5
- movem.w (a4)+,d0-d2
-
- movea.l d7,a1
- lsr.w #8,d1
- move.b d1,d2
- add.b d2,d2
- lea (a1,d2.w*2),a1
-
- move.l d0,d1
- bpl.s .xpos1
- neg.l d1
- lea (a2,d1.l*2),a2
- moveq #0,d0
- .xpos1: lea (a3,d0.l*4),a0
- cmpi.w #envmapxres-1,d3
- blt.s .nottoobig
- move.w d3,d2
- subi.w #envmapxres-1,d2
- sub.w d2,d3
- .nottoobig:
- sub.w d0,d3
- bmi.s .endfirstline
-
- .pixloop:
- move.w (a2)+,d1
- move.l (a1,d1.w),(a0)+
- dbra d3,.pixloop
-
- .endfirstline:
- lea scrxbytes(a3),a3
- dbra d5,.firstloop
- .endplotfirst:
-
- * Plot lower part of triangle..
- .plotsecond:
- subq.w #1,d6
- bmi.s .endsecond * Triangle is a /\ or a \/
- * Test if left or right was shorter..
- btst #31,d6 * Which edge is longest?
- bne.s .noswaplr
- lea edgeheadersize(a6),a4
- move.w d6,d5
- sub.w d6,d6
- bra .firstloop
-
- .noswaplr:
- move.w d6,d5
- sub.w d6,d6
- lea edgeheadersize(a6),a5
- bra .firstloop
-
- .endsecond:
-
- .endscanplot:
-
- .rts: rts
-
- .edgestartadr:
- DS.L 1
- .textureadr:
- DS.L 1
- .textureoffset_tbl:
- DS.W scrxbytes/2
-
- ********
-
- ;ROUTINE SWITCHES VISIBLE SCREEN AND CYCLES THE SCREENADRESSES
- switch_screens:
- lea scr,a1
- move.l (a1)+,a0
- move.l (a1)+,d1
- move.l (a1),-4(a1)
- move.l a0,(a1)
- move.l d1,-8(a1)
- bsr set_scradr
- rts
-
- ******** DATA ********
-
- DATA
-
- envobjadr:
- DC.L torusobject_buf
- envtextureadr:
- DC.L texture_dat
- torusobject_buf:
- INCBIN DIABLO.DAT
- ;INCBIN TORUS.DAT
- EVEN
- texture_dat:
- INCBIN FLAREWVE.APX
- ;INCBIN FLAREPLS.APX
- ;INCBIN FLARECLD.APX
- ;INCBIN PSYCH.APX
- ;INCBIN STONE.APX
- ;INCBIN WOBBEL.APX
- ;INCBIN BLOB2.RAW
- sine_tbl:
- INCBIN SINUS.DAT
-
- ******** BSS ********
-
- BSS
-
- boundbox_tbl:
- DS.W 8*3 * 8 points in box
-
- points_tbl:
- DS.W 1 * number of 3d-points in object
- DS.W pointsize*maxpoints * X,Y,TX,TY,Z
- pnttritbladr:
- DS.L 1
- edgestbladr:
- DS.L 1
- tritbladr:
- DS.L 1
- normaltbladr:
- DS.L 1
-
- temp_buf:
- DS.L 512*256
-
- scr: DS.L 3
- scr_buf:
- DS.L (scrsize/4)*3